﻿using StructuredProgrammingAssignment.Helpers;
using StructuredProgrammingAssignment.Linq;
using System;
using System.Linq;

namespace StructuredProgrammingAssignment.Controllers
{
	public class UserAccountController : SPApiController
	{
		/**
		 * Log into a specific user account.
		 **/
		[System.Web.Http.AcceptVerbs("GET", "POST")]
		public Object[] LogIn(String email = "", String password = "") {
			try {
				// Check for validity
				SPDataContext db = new SPDataContext();
				UserAccount account = (from a in db.UserAccounts
									   where a.Email.Equals(email) && a.Password.Equals(SPHelper.GetSHA1HashData(password))
									   select a).FirstOrDefault();

				// Return
				if (account != null) {
					return SuccessResult(SPHelper.JsonUserAccount(account));
				} else {
					return FailureResult("Login failed");
				}
			} catch (Exception e) {
				return ExceptionResult(e);
			}
		} // LogIn

		/**
		 * Register a new user account.
		 **/
		[System.Web.Http.AcceptVerbs("GET", "POST")]
		public Object[] Register(String email, String password, String firstname, String lastname, String properties = null) {
			try {
				if (email != null && !SPHelper.isValidEmail(email)) {
					return FailureResult("Invalid email.", "input validation error");
				}

				if (password.Length < 6) {
					return FailureResult("Password is too short.", "input validation error");
				}

				// Init new user account
				SPDataContext db = new SPDataContext();
				UserAccount account = new UserAccount {
					Email = email,
					Password = password,
					FirstName = firstname,
					LastName = lastname,
					Properties = properties
				};

				// Submit & return
				db.UserAccounts.InsertOnSubmit(account);
				db.SubmitChanges();

				account = (from a in db.UserAccounts
						   where a.Email.Equals(email)
						   select a).FirstOrDefault();

				return SuccessResult(SPHelper.JsonUserAccount(account));
			} catch (Exception e) {
				return ExceptionResult(e);
			}
		} // Register

		/**
		 * Edit info of a user account.
		 **/
		[System.Web.Http.AcceptVerbs("GET", "POST")]
		public Object[] Edit(
			String id,							// user id, used for authorization
			String email = null,
			String password = null,
			String firstname = null,
			String lastname = null,
			String properties = null,
			String comfirmPassword = null
		) {
			try {
				SPDataContext db = new SPDataContext();

				// Authorization
				Guid parsedUserId;
				if (!Guid.TryParse(id, out parsedUserId)) {
					return FailureResult("You are not authorized to execute this operation.", "authorization error");
				}
				// Double check
				UserAccount account = (from a in db.UserAccounts
									   where a.Id.Equals(parsedUserId)
									   select a).FirstOrDefault();
				if (account == null) {
					return FailureResult("You are not authorized to execute this operation.", "authorization error");
				}

				if (email != null && !SPHelper.isValidEmail(email)) {
					return FailureResult("Invalid email.", "input validation error");
				}

				if (email == null && password == null && firstname == null && lastname == null && properties == null) {
					LogWarning("user account might not be edited properly.");
				}

				// Update
				if (email != null) {
					account.Email = email;
				}
				if (password != null) {
					if (password.Length < 6) {
						return FailureResult("Password is too short.", "input validation error");
					}

					if (!account.Password.Equals(comfirmPassword)) {
						return FailureResult("Invalid password.", "invalid password");
					}

					account.Password = password;
				}
				if (firstname != null) {
					account.FirstName = firstname;
				}
				if (lastname != null) {
					account.LastName = lastname;
				}
				if (properties != null) {
					account.Properties = properties;
				}

				// Submit changes & return
				db.SubmitChanges();

				return SuccessResult(SPHelper.JsonUserAccount(account));
			} catch (Exception e) {
				return ExceptionResult(e);
			}
		} // Edit

	} // UserAccountController
}
